package com.dragon.aipictures.manager.sharding.test;

public class EnhancedSnowflake {
    private static final long SEQUENCE_BITS = 12L;
    private static final long MAX_SEQUENCE = (1L << SEQUENCE_BITS) - 1;
    private static long lastTimestamp = -1L;
    private static long sequence = 0L;

    public static synchronized long nextId(int workerId) {
        long currentTimestamp = timeGen();
        
        // 时钟回拨处理
        if (currentTimestamp < lastTimestamp) {
            long offset = lastTimestamp - currentTimestamp;
            if (offset <= 100) { // 允许100ms内的回拨，等待
                try {
                    Thread.sleep(offset);
                } catch (InterruptedException e) {
                    throw new RuntimeException("Clock moved backwards, wait interrupted");
                }
                currentTimestamp = timeGen();
            } else { // 严重回拨，抛出异常
                throw new RuntimeException("Clock moved backwards, refusing to generate id");
            }
        }

        if (currentTimestamp == lastTimestamp) {
            sequence = (sequence + 1) & MAX_SEQUENCE;
            if (sequence == 0) { // 当前毫秒序列号用尽，等待下一毫秒
                currentTimestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }

        lastTimestamp = currentTimestamp;
        
        // 组合ID：时间戳 | workerId | 序列号
        return (currentTimestamp << (SEQUENCE_BITS + 10))
                | (workerId << SEQUENCE_BITS)
                | sequence;
    }

    private static long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    private static long timeGen() {
        return System.currentTimeMillis();
    }
}